﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace LambdaToSql
{
    /// <summary>
    /// 转换统一入口
    /// </summary>
    public class SqlClient
    {
        /// <summary>
        /// 上下文对象
        /// </summary>
        public LambdaToSql.EntityModel.DbContext Context { get; set; }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public SqlClient()
        {
            this.Context = new LambdaToSql.EntityModel.DbContext();
            this.Context.InitRegister();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public SqlClient(LambdaToSql.EntityModel.DbContext context)
        {
            this.Context = context;
            this.Context.InitRegister();
        }

        /// <summary>
        /// Ado查询
        /// </summary>
        public DbHelper.IDBhelper Ado
        {
            get
            {
                var obj = new DbHelper.MsSqlServer() { Context = this.Context };
                return obj;
            }
        }

        /// <summary>
        /// 生成数据库表对应的实体
        /// </summary>
        public LambdaToSql.Interface.IDbFirst DbFirst
        {
            get
            {
                var obj = new DbFirst() { Context = this.Context };
                return obj;
            }
        }

        #region 事务

        /// <summary>
        /// 开始事务
        /// </summary>
        public virtual void BeginTran()
        {
            if (this.Context.TransConnection == null)
            {
                this.Context.TransConnection = new SqlConnection(this.Context.ConnectionString);
            }
            if (this.Context.TransConnection.State == ConnectionState.Closed)
            {
                this.Context.TransConnection.Open();
            }
            this.Context.Trans = this.Context.TransConnection.BeginTransaction();
        }

        /// <summary>
        /// 提交数据库事务。
        /// </summary>
        public virtual void CommitTran()
        {
            this.Context.Trans.Commit();
            this.Context.TransConnection.Close();
            this.Context.Trans = null;
        }

        /// <summary>
        /// 回滚事务
        /// </summary>
        public virtual void RollbackTran()
        {
            this.Context.Trans.Rollback();
            this.Context.TransConnection.Close();
            this.Context.Trans = null;
        }
        #endregion

        #region 查询

        /// <summary>
        /// 查询全部数据 
        /// <para>数据量大请使用分页查询</para>
        /// </summary>
        public virtual LambdaToSql.Interface.IQueryable<T> QueryTable<T>() where T : class, new()
        {
            var result = (LambdaToSql.Interface.IQueryable<T>)GetReflectionObj<T>("Queryable");
            return result;
        }

        /// <summary>
        /// 条件查询
        /// </summary>
        public virtual LambdaToSql.Interface.IQueryable<T> QueryTable<T>(Expression<Func<T, bool>> exp) where T : class, new()
        {
            var result = (LambdaToSql.Interface.IQueryable<T>)GetReflectionObj<T>("Queryable");
            return result.Where(exp);
        }
        #endregion

        #region 添加

        /// <summary>
        /// 添加对象
        /// </summary>
        public virtual LambdaToSql.Interface.IInsertable<T> InsertTble<T>(T t) where T : class, new()
        {
            var result = (LambdaToSql.Interface.IInsertable<T>)GetReflectionObj<T>("Insertable");
            return result.Insert(t);
        }
        #endregion

        #region 更新

        /// <summary>
        /// 更新对象
        /// </summary>
        public virtual LambdaToSql.Interface.IUpdateable<T> UpdateTble<T>(T t) where T : class, new()
        {
            var result = (LambdaToSql.Interface.IUpdateable<T>)GetReflectionObj<T>("Updateable");
            return result.Update(t);
        }
        #endregion

        #region 删除

        /// <summary>
        /// 删除全部对象
        /// <para>慎用</para>
        /// </summary>
        public virtual LambdaToSql.Interface.IDeleteable<T> DeleteTble<T>() where T : class, new()
        {
            var result = (LambdaToSql.Interface.IDeleteable<T>)GetReflectionObj<T>("Deleteable");
            return result;
        }

        /// <summary>
        /// 删除对象
        /// <para>主键必须赋值 使用主键作为删除条件</para>
        /// </summary>
        public virtual LambdaToSql.Interface.IDeleteable<T> DeleteTble<T>(T t) where T : class, new()
        {
            var result = (LambdaToSql.Interface.IDeleteable<T>)GetReflectionObj<T>("Deleteable");
            return result.Delete(t);
        }

        /// <summary>
        /// 条件删除
        /// </summary>
        public virtual LambdaToSql.Interface.IDeleteable<T> DeleteTble<T>(Expression<Func<T, bool>> exp) where T : class, new()
        {
            var result = (LambdaToSql.Interface.IDeleteable<T>)GetReflectionObj<T>("Deleteable");
            return result.Where(exp);
        }
        #endregion

        #region 获取反射实例化对象

        /// <summary>
        /// 根据类名称 获取反射实例化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        private object GetReflectionObj<T>(string name) where T : class, new()
        {
            string assemblyName = "LambdaToSql";
            string fullClassName = string.Format("LambdaToSql.Realization.{0}.{1}`1", this.Context.SqlType.ToString(), name);
            var result = (LambdaToSql.Interface.IQueryable<T>)LambdaToSql.FrameWork.Tools.GetReflectionObj<T>(assemblyName, fullClassName, this.Context);
            return result;
        }
        #endregion
    }
}
